//! # RustCloud 性能基准测试
//! 
//! 使用Criterion进行性能基准测试

use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId};
use tokio::runtime::Runtime;
use rustcloud::prelude::*;
use rustcloud::performance::*;
use std::sync::Arc;
use std::time::Duration;

/// 框架启动性能基准测试
fn benchmark_framework_startup(c: &mut Criterion) {
    let rt = Runtime::new().unwrap();
    
    c.bench_function("framework_startup", |b| {
        b.to_async(&rt).iter(|| async {
            let framework = AdvancedRustCloudBuilder::new("benchmark-service")
                .for_development()
                .build()
                .await
                .unwrap();
            
            framework.start().await.unwrap();
            let _config = black_box(framework.get_config());
            framework.stop().await.unwrap();
        });
    });
}

/// 服务发现性能基准测试
fn benchmark_service_discovery(c: &mut Criterion) {
    let rt = Runtime::new().unwrap();
    
    let framework = rt.block_on(async {
        let framework = AdvancedRustCloudBuilder::new("discovery-benchmark")
            .build()
            .await
            .unwrap();
        framework.start().await.unwrap();
        framework
    });

    c.bench_function("service_discovery", |b| {
        b.to_async(&rt).iter(|| async {
            let _instances = black_box(
                framework.discover_services("test-service").await.unwrap_or_default()
            );
        });
    });

    rt.block_on(async {
        framework.stop().await.unwrap();
    });
}

/// 负载均衡性能基准测试
fn benchmark_load_balancing(c: &mut Criterion) {
    let rt = Runtime::new().unwrap();
    
    let framework = rt.block_on(async {
        let framework = AdvancedRustCloudBuilder::new("lb-benchmark")
            .build()
            .await
            .unwrap();
        framework.start().await.unwrap();
        framework
    });

    c.bench_function("load_balancing", |b| {
        b.to_async(&rt).iter(|| async {
            let _instance = black_box(
                framework.select_service_instance("test-service").await.unwrap_or_default()
            );
        });
    });

    rt.block_on(async {
        framework.stop().await.unwrap();
    });
}

/// 连接池性能基准测试
fn benchmark_connection_pool(c: &mut Criterion) {
    let rt = Runtime::new().unwrap();
    
    let config = ConnectionPoolConfig {
        max_connections: 100,
        min_connections: 10,
        connection_timeout: Duration::from_secs(5),
        idle_timeout: Duration::from_secs(60),
        acquire_timeout: Duration::from_secs(3),
        validation_interval: Duration::from_secs(30),
    };

    let factory = Arc::new(TestConnectionFactory::new());
    let pool = rt.block_on(async {
        let pool = ConnectionPool::new(config, factory);
        pool.initialize().await.unwrap();
        pool
    });

    c.bench_function("connection_pool_acquire", |b| {
        b.to_async(&rt).iter(|| async {
            let conn = black_box(pool.acquire().await.unwrap());
            pool.release(&conn.id).await.unwrap();
        });
    });

    rt.block_on(async {
        pool.shutdown().await.unwrap();
    });
}

/// 内存管理性能基准测试
fn benchmark_memory_management(c: &mut Criterion) {
    let rt = Runtime::new().unwrap();
    
    let gc_config = GcConfig {
        auto_gc_enabled: false, // 手动控制GC
        gc_threshold: 0.8,
        gc_interval: Duration::from_secs(10),
        pressure_threshold: 0.9,
    };
    
    let memory_manager = rt.block_on(async {
        let manager = MemoryManager::new(gc_config);
        manager.create_pool("benchmark_pool".to_string(), 1024, 1000).await.unwrap();
        manager
    });

    c.bench_function("memory_allocation", |b| {
        b.to_async(&rt).iter(|| async {
            let block = black_box(memory_manager.allocate("benchmark_pool").await.unwrap());
            memory_manager.deallocate("benchmark_pool", block).await.unwrap();
        });
    });
}

/// 异步任务池性能基准测试
fn benchmark_async_task_pool(c: &mut Criterion) {
    let rt = Runtime::new().unwrap();
    
    let task_pool = AsyncTaskPool::new(num_cpus::get());

    let mut group = c.benchmark_group("async_task_pool");
    
    for task_count in [10, 50, 100, 500].iter() {
        group.bench_with_input(
            BenchmarkId::new("submit_tasks", task_count),
            task_count,
            |b, &task_count| {
                b.to_async(&rt).iter(|| async {
                    let counter = Arc::new(tokio::sync::RwLock::new(0));
                    
                    for _ in 0..task_count {
                        let counter_clone = counter.clone();
                        task_pool.submit(move || {
                            let rt = tokio::runtime::Handle::current();
                            rt.block_on(async {
                                let mut count = counter_clone.write().await;
                                *count += 1;
                            });
                        }).await.unwrap();
                    }
                    
                    // 等待所有任务完成
                    loop {
                        let count = *counter.read().await;
                        if count == task_count {
                            break;
                        }
                        tokio::time::sleep(Duration::from_millis(1)).await;
                    }
                    
                    black_box(counter);
                });
            },
        );
    }
    group.finish();
}

/// 指标收集性能基准测试
fn benchmark_metrics_collection(c: &mut Criterion) {
    let rt = Runtime::new().unwrap();
    
    let collector = rt.block_on(async {
        MemoryMetricsCollector::new()
    });

    c.bench_function("metrics_collection", |b| {
        b.to_async(&rt).iter(|| async {
            let labels = std::collections::HashMap::new();
            
            black_box(collector.record_counter("test_counter", 1.0, labels.clone()).await.unwrap());
            black_box(collector.set_gauge("test_gauge", 42.0, labels.clone()).await.unwrap());
            black_box(collector.record_histogram("test_histogram", 123.0, labels).await.unwrap());
        });
    });
}

/// 并发性能基准测试
fn benchmark_concurrent_operations(c: &mut Criterion) {
    let rt = Runtime::new().unwrap();
    
    let framework = rt.block_on(async {
        let framework = AdvancedRustCloudBuilder::new("concurrent-benchmark")
            .enable_metrics()
            .build()
            .await
            .unwrap();
        framework.start().await.unwrap();
        framework
    });

    let mut group = c.benchmark_group("concurrent_operations");
    
    for concurrency in [1, 5, 10, 20, 50].iter() {
        group.bench_with_input(
            BenchmarkId::new("concurrent_health_checks", concurrency),
            concurrency,
            |b, &concurrency| {
                b.to_async(&rt).iter(|| async {
                    let mut tasks = Vec::new();
                    
                    for _ in 0..concurrency {
                        let framework_clone = framework.clone();
                        tasks.push(tokio::spawn(async move {
                            framework_clone.health_check().await
                        }));
                    }
                    
                    let results: Vec<_> = futures::future::join_all(tasks).await;
                    black_box(results);
                });
            },
        );
    }
    group.finish();

    rt.block_on(async {
        framework.stop().await.unwrap();
    });
}

/// 测试连接工厂
struct TestConnectionFactory;

impl TestConnectionFactory {
    fn new() -> Self {
        Self
    }
}

#[async_trait::async_trait]
impl ConnectionFactory<TestConnection> for TestConnectionFactory {
    async fn create_connection(&self) -> ServiceResult<TestConnection> {
        Ok(TestConnection {
            id: uuid::Uuid::new_v4().to_string(),
            created_at: std::time::Instant::now(),
        })
    }

    async fn validate_connection(&self, _connection: &TestConnection) -> bool {
        true
    }

    async fn destroy_connection(&self, _connection: TestConnection) -> ServiceResult<()> {
        Ok(())
    }
}

/// 测试连接
#[derive(Debug, Clone)]
struct TestConnection {
    id: String,
    created_at: std::time::Instant,
}

criterion_group!(
    benches,
    benchmark_framework_startup,
    benchmark_service_discovery,
    benchmark_load_balancing,
    benchmark_connection_pool,
    benchmark_memory_management,
    benchmark_async_task_pool,
    benchmark_metrics_collection,
    benchmark_concurrent_operations
);

criterion_main!(benches);